package com.baomidou.ant.controller;


import com.baomidou.ant.common.Result;
import com.baomidou.ant.entity.*;
import com.baomidou.ant.service.*;
import com.baomidou.ant.utils.*;
import com.baomidou.ant.vo.Request.*;
import com.baomidou.ant.vo.Response.ResponseMyPvpRecordVo;
import com.baomidou.ant.vo.Response.ResponseUserListVo;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.google.code.kaptcha.Constants;
import com.google.code.kaptcha.Producer;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author jobob
 * @since 2021-03-24
 */
@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    public RedisTemplate redisTemplate;
    @Autowired
    public Producer producer;
    @Autowired
    public IUserService userService;
    @Autowired
    public IPvpRecordService pvpRecordService;



    //验证码接口---String类型
    @GetMapping("/captcha.jpg")
    public void captcha(HttpServletResponse response,HttpServletRequest request)throws IOException {
        response.setHeader("Cache-Control", "no-store, no-cache");
        response.setContentType("image/jpeg");
        //生成文字验证码
        String text = producer.createText();
        //生成图片验证码
        BufferedImage image = producer.createImage(text);
       /* //缓存验证码code,存入session中
        HttpSession session = request.getSession();
        session.setAttribute(Constants.KAPTCHA_SESSION_KEY,text);
        //设置过期时间300s
        session.setMaxInactiveInterval(300);*/
        ValueOperations forValue = redisTemplate.opsForValue();
        forValue.set(Constants.KAPTCHA_SESSION_KEY,text);
        redisTemplate.expire(Constants.KAPTCHA_SESSION_KEY, 300, TimeUnit. SECONDS);

        ServletOutputStream out = response.getOutputStream();
        ImageIO.write(image, "jpg", out);
        IOUtils.closeQuietly(out);
    }


    //短信验证码接口----int类型
    @GetMapping("/sendSms/{mobile}")
    public Result sendSms(@PathVariable("mobile") String mobile){
        //生成 6 位短信验证码
        Random random=new Random();
        int max=999999;
        int min=100000;
        int code = random.nextInt(max);//code是int类型
        if(code<min){
            code=code+min;
        }
        //System.out.println(mobile+"收到验证码是："+code);
        //发送实现
        SmsUtil smsUtil = new SmsUtil();
        Map<String,String> map = new HashMap<>();
        //把code和手机号存入map中，调用发送方法发送验证码
        map.put("code",code + "");
        map.put("mobile",mobile);
        smsUtil.readyToSend(map);
        //保存到redis
        ValueOperations forValue = redisTemplate.opsForValue();
        forValue.set(Constants.KAPTCHA_SESSION_KEY,code);
        redisTemplate.expire(Constants.KAPTCHA_SESSION_KEY, 60, TimeUnit. SECONDS);
        return Result.getSuccess();
    }

    //注册接口
    @PostMapping("/register")
    public Result register(@RequestBody RequestRegisterVo requestRegisterVo, HttpServletRequest request){
        //信息为空
        if (VoUtilsTool.checkObjFieldIsNull(requestRegisterVo)){
            return Result.getFailure().setMsg("缺少信息");
        }
        //电话格式错误
        if (!FormatUtils.isMobile(requestRegisterVo.getTelephone())){
            return Result.getFailure().setMsg("电话格式错误");
        }
        //用户已经存在————手机号被注册
        if(ObjectUtils.isNotEmpty(userService.queryByTel(requestRegisterVo.getTelephone()))){
            return Result.getFailure().setMsg("该手机已经注册!");
        }
        //用户名存在
        if(ObjectUtils.isNotEmpty(userService.queryByName(requestRegisterVo.getUsername()))){
            return Result.getFailure().setMsg("用户名已经存在");
        }
        //判断手机验证码是否正确
        Integer trueCode = (Integer) redisTemplate.opsForValue().get(Constants.KAPTCHA_SESSION_KEY);
        if (!trueCode.equals(requestRegisterVo.getCode())) {
            return Result.getFailure().setMsg("短信验证码错误");
        }
        //保存成功
        userService.register(requestRegisterVo);

        //完成注册
        return Result.getSuccess().setMsg("注册成功");
    }

    //登录接口----密码验证码登录
    @PostMapping("/login")
    public Result login(@RequestBody LoginRequestVo loginRequestVo) throws IOException{
        //拿到验证码
       /* HttpSession session = request.getSession();
        String trueCode =(String) session.getAttribute(Constants.KAPTCHA_SESSION_KEY);*/
        String trueCode = (String) redisTemplate.opsForValue().get(Constants.KAPTCHA_SESSION_KEY);
        //信息为空
        if (VoUtilsTool.checkObjFieldIsNull(loginRequestVo)){
            return Result.getFailure().setMsg("请输入完整信息");
        }
        //查询用户是否正确
        User user = userService.queryByTel(loginRequestVo.getTelephone());
        //用户不存在，利用手机号判断
        if (ObjectUtils.isEmpty(user)) {
            return Result.getFailure().setMsg("用户不存在");
        }
        //密码错误
        if (!Md5Utils.hash(loginRequestVo.getPassword()).equals(user.getPassword())) {
            return Result.getFailure().setMsg("密码错误");
        }
        if (!trueCode.equalsIgnoreCase(loginRequestVo.getCaptcha())) {
            return Result.getFailure().setMsg("验证码错误");
        }
        //用户存在且密码正确
        Map<String,Object> result=new HashMap<>();
        result.put("userId",user.getId());
        //判断是否为管理员
        if(user.getType()){
            result.put("isAdmin",true);
            return Result.getSuccess().setData(result);
        }else {
            result.put("isAdmin",false);
        }
        return Result.getSuccess().setData(result);
    }

    //登录接口----手机验证码登录
    @PostMapping("/loginByTel")
    public Result loginByTel(@RequestBody LoginByTelRequestVo loginByTelRequestVo, HttpServletRequest request)throws IOException{
        //各项信息是否正确
        User user = userService.queryByTel(loginByTelRequestVo.getTelephone());
        //用户不存在，利用手机号判断
        if (ObjectUtils.isEmpty(user)) {
            return Result.getFailure().setMsg("用户不存在");
        }
        //判断手机验证码是否正确
        Integer code = (Integer) redisTemplate.opsForValue().get(Constants.KAPTCHA_SESSION_KEY);
        if (!code.equals(loginByTelRequestVo.getCode())) {
            return Result.getFailure().setMsg("短信验证码错误");
        }
        //用户存在且手机验证码正确
        Map<String,Object> result=new HashMap<>();
        result.put("userId",user.getId());
        //判断是否为管理员
        if(user.getType()){
            result.put("isAdmin",true);
            return Result.getSuccess().setData(result);
        }else {
            result.put("isAdmin",false);
        }
        return Result.getSuccess().setData(result);
    }

    //修改密码----通过原密码
    @PostMapping("/changePassword")
    public Result changePassword(@RequestBody RequestChangePasswordVo requestChangePasswordVo) {
        User user = userService.getById(requestChangePasswordVo.getId());
        //与原密码比较
        if (user.getPassword().equals(Md5Utils.hash(requestChangePasswordVo.getPassword()))) {
            //加密新密码
            user.setPassword(Md5Utils.hash(requestChangePasswordVo.getNewPassword()));
            //保存
            userService.updateById(user);
            return Result.getSuccess().setMsg("修改成功");
        } else {
            return Result.getFailure().setMsg("原密码不正确");
        }
    }

    //忘记密码-----手机验证码实现
    @PostMapping("/findPassword")
    public Result findPassword(@RequestBody RequestFindPasswordVo requestFindPasswordVo, HttpServletRequest request){
        //信息为空
        if (VoUtilsTool.checkObjFieldIsNull(requestFindPasswordVo)){
            return Result.getFailure().setMsg("请填写必要信息");
        }
        //查询用户是否正确
        User user = userService.queryByTel(requestFindPasswordVo.getTelephone());
        //用户不存在，利用手机号判断
        if (ObjectUtils.isEmpty(user)) {
            return Result.getFailure().setMsg("用户不存在");
        }
        //判断手机验证码是否正确
            //先获取session中的手机验证码
        HttpSession session = request.getSession();
        Integer trueCaptcha = (Integer) session.getAttribute(Constants.KAPTCHA_SESSION_KEY);
            //判断是否正确
        if (!trueCaptcha.equals(requestFindPasswordVo.getCode())){
            return Result.getFailure().setMsg("短信验证码错误");
        }else {
            //新密码修改
            User user1 = userService.queryByTel(requestFindPasswordVo.getTelephone());
            //加密新密码
            user1.setPassword(Md5Utils.hash(requestFindPasswordVo.getNewPassword()));
            //保存
            userService.updateById(user1);
            return Result.getSuccess().setMsg("设置新密码成功");
        }
    }


    //修改基本信息接口
    @PostMapping("/updateInfo")
    public Result update(@RequestBody RequestUpdateUserInfoVo requestUpdateUserInfoVo,HttpServletRequest request){
        User user=userService.getById(requestUpdateUserInfoVo.getId());
        //空项则保留原来的值
        if(ObjectUtils.isNotEmpty(requestUpdateUserInfoVo.getCity())){
            requestUpdateUserInfoVo.setCity(user.getCity());
        }
        if(ObjectUtils.isNotEmpty(requestUpdateUserInfoVo.getProvince())){
            requestUpdateUserInfoVo.setProvince(user.getProvince());
        }
        BeanUtils.copyProperties(requestUpdateUserInfoVo,user);
        userService.saveOrUpdate(user);
        return Result.getSuccess().setMsg("修改成功!");

    }

    //判断旧手机接口
    @PostMapping("/isOldTel")
    public Result isOldTel(@RequestBody RequestUpdateTelVo requestUpdateTelVo,HttpServletRequest request){
        if (ObjectUtils.isEmpty(requestUpdateTelVo.getCode())){
            return Result.getFailure().setMsg("请填写验证码");
        }
        //获取session中的手机验证码
        HttpSession session = request.getSession();
        Integer trueCode = (Integer) session.getAttribute(Constants.KAPTCHA_SESSION_KEY);
        if (!trueCode.equals(requestUpdateTelVo.getCode())) {
            return Result.getFailure().setMsg("短信验证码错误");
        }else
            return Result.getSuccess().setMsg("验证成功");
    }

    //修改绑定电话接口
    @PostMapping("/updateTel")
    public Result updateTel(@RequestBody RequestUpdateTelVo requestUpdateTelVo,HttpServletRequest request){
        //信息为空
        if (VoUtilsTool.checkObjFieldIsNull(requestUpdateTelVo)){
            return Result.getFailure().setMsg("请填写必要信息");
        }
        //电话格式错误
        if (!FormatUtils.isMobile(requestUpdateTelVo.getTelephone())){
            return Result.getFailure().setMsg("电话格式错误");
        }
        //用户已经存在————手机号被注册
        if(ObjectUtils.isNotEmpty(userService.queryByTel(requestUpdateTelVo.getTelephone()))){
            return Result.getFailure().setMsg("该手机已经注册!");
        }
        //判断手机验证码是否正确
        if (ObjectUtils.isEmpty(requestUpdateTelVo.getCode())){
            return Result.getFailure().setMsg("请填写验证码");
        }
        HttpSession session = request.getSession();
        Integer trueCode = (Integer) session.getAttribute(Constants.KAPTCHA_SESSION_KEY);
        if (!trueCode.equals(requestUpdateTelVo.getCode())) {
            return Result.getFailure().setMsg("短信验证码错误");
        }
        User user=userService.getById(requestUpdateTelVo.getUserId());
        user.setTelephone(requestUpdateTelVo.getTelephone());
        userService.saveOrUpdate(user);
        return Result.getSuccess().setMsg("修改成功");
    }

    //分页查询用户信息
    @PostMapping("/list")
    public Result list(@RequestBody RequestUserListVo requestUserListVo){
        IPage<ResponseUserListVo> iPage=userService.userList(requestUserListVo);
        return Result.getSuccess().setData(iPage);
    }

    //通过id查询用户
    @GetMapping("/getUserInfoById/{userId}")
    public Result getUserInfoById(@PathVariable Integer userId){
        User user=userService.getById(userId);
        ResponseUserListVo vo=new ResponseUserListVo();
        //属性拷贝
        if(ObjectUtils.isNotNull(user)){
            BeanUtils.copyProperties(user,vo);
            return Result.getSuccess().setData(vo);
        }else {
            return Result.getFailure().setMsg("用户不存在");
        }
    }

    //批量删除用户
    @DeleteMapping("/deleteByIds")
    public Result deleteByIds(@RequestBody RequestDeleteVo requestDeleteVo){
        List<Integer> ids= Arrays.asList(requestDeleteVo.getIds());
        if(ids.size()>0&&userService.removeByIds(ids)){
            return Result.getSuccess().setMsg("删除成功");
        }else{
            return Result.getFailure().setMsg("删除失败");
        }
    }

    //通过id删除
    @DeleteMapping("/delete/{userId}")
    public Result delete(@PathVariable Integer userId){
        if(userService.removeById(userId)){
            return Result.getSuccess().setMsg("删除成功!");
        }else {
            return Result.getFailure().setMsg("删除失败!");
        }
    }

    //上传用户头像,通过用户id上传
    @RequestMapping("/upload/{userId}")
    public Result upload(@RequestParam("file") MultipartFile file, HttpServletRequest request, @PathVariable Integer userId) {
        String path = userService.upload(file);
        //保存头像路径
        HttpSession session=request.getSession();
        session.setAttribute("path",path);
        User user =userService.getById(userId);
        user.setUserImage((String)session.getAttribute("path"));
        userService.saveOrUpdate(user);
        return Result.getSuccess().setMsg("上传成功");
    }

    //管理员修改用户信息
    @PostMapping("/updateByAdmin")
    public Result updateByAdmin(){
        return null;
    }

    //钻石换积分
    @PostMapping("/exchangePoints")
    public Result exchangePoints(@RequestBody RequestExchangePointsVo vo){
        User user=userService.getById(vo.getUserId());
        //需要钻石消耗量,1:100,钻石：积分
        Integer diamonds=vo.getPoints()/100;
        if(user.getDiamonds()<diamonds){
            return Result.getFailure().setMsg("钻石不足请充值!");
        }else{
            user.setDiamonds(user.getDiamonds()-diamonds);
            user.setPoints(user.getPoints()+vo.getPoints());
        }
        userService.saveOrUpdate(user);
        return Result.getSuccess().setMsg("兑换成功");
    }

    //个人信息栏展示对战数据
    @GetMapping("/listRecord/{userId}")
    public Result  listRecord(@PathVariable Integer userId){
        PvpRecord pvpRecord=pvpRecordService.getByUserId(userId);
        ResponseMyPvpRecordVo responseMyPvpRecordVo=new ResponseMyPvpRecordVo();
        responseMyPvpRecordVo.setWin(pvpRecord.getWin());
        responseMyPvpRecordVo.setFail(pvpRecord.getFail());
        Double rate=(double)pvpRecord.getWin()/(double)pvpRecord.getTotal()*100;
        responseMyPvpRecordVo.setWinningRate(Double.parseDouble(String.format("%.2f",rate)));
        return Result.getSuccess().setData(responseMyPvpRecordVo);
    }




}
